use std::{
    collections::{BTreeMap, HashMap},
    io::Cursor,
    sync::Arc,
};

use futures::SinkExt;
use serde_json::json;
use tokio::{
    io::{AsyncReadExt, AsyncWriteExt},
    net::{
        tcp::{OwnedReadHalf, OwnedWriteHalf},
        TcpStream,
    },
    sync::Mutex,
    task::spawn_blocking,
};

use crate::{
    meet::Meet,
    message::{parse, Chat, Message, OperationType, Opration},
    server::Server,
};

#[derive(Debug)]
// 用户信息
// 与服务端连接套接字
pub struct User {
    pub read: Arc<Mutex<OwnedReadHalf>>,
    pub write: Arc<Mutex<OwnedWriteHalf>>,
    // 昵称
    pub name: String,
    // cc号
    pub cc_no: String,
    //是否上线
    pub onlin: bool,
    // 好友列表
    pub friends: Arc<Mutex<BTreeMap<String, Arc<Mutex<User>>>>>,
    //  群聊列表
    pub meets: BTreeMap<String, Arc<Mutex<Meet>>>,
    // 别人发来添加好友/群聊的请求
    pub add_quest: Arc<Mutex<BTreeMap<String, Opration>>>,
    // 服务器
    server: Arc<Mutex<Server>>,
}

impl User {
    pub fn new(
        connection: TcpStream,
        cc_no: String,
        server: Arc<Mutex<Server>>,
    ) -> Arc<Mutex<Self>> {
        let (read, write) = connection.into_split();
        let user = Self {
            read: Arc::new(Mutex::new(read)),
            write: Arc::new(Mutex::new(write)),
            name: cc_no.clone(),
            cc_no,
            onlin: true,
            friends: Arc::new(Mutex::new(BTreeMap::new())),
            meets: BTreeMap::new(),
            add_quest: Arc::new(Mutex::new(BTreeMap::new())),
            server,
        };
        let user_arc = Arc::new(Mutex::new(user));
        // let user_clone = user_arc.clone();
        // tokio::spawn(async move {
        //     let mut user_lock = user_clone.lock().await;
        //     for (meet_no, meet) in &user_lock.meets {
        //         let meet = meet.lock().await;
        //         let mut rx = meet.broadcast.subscribe();
        //         while let Ok(msg) = rx.recv().await {
        //             user_lock
        //                 .connection
        //                 .lock()
        //                 .await
        //                 .write_all(&msg)
        //                 .await
        //                 .unwrap();
        //         }
        //     }
        // });
        user_arc
    }
    pub async fn handler(&self) {
        let read_clone = self.read.clone();
        let write_clone = self.write.clone();
        let server_clone = self.server.clone();
        let self_cc_no = Arc::new(self.cc_no.clone());
        let friends_arc = self.friends.clone();
        let add_request_arc = self.add_quest.clone();

        tokio::spawn(async move {
            let self_cc_no = self_cc_no.clone().as_ref().clone();
            let mut buf = [0; 1024];
            loop {
                let mut read_lock = read_clone.lock().await;
                let n = read_lock.read(&mut buf).await.unwrap();
                drop(read_lock);
                if n == 0 {
                    // 客户端关闭连接
                    server_clone.lock().await.remove_user(self_cc_no.clone());
                    return;
                }
                let mut src = Cursor::new(&buf[..n]);
                // 格式化消息信息
                match parse(&mut src) {
                    Some(opration) => {
                        let message = &opration.message.clone();
                        log::info!("option:{:?}", opration);
                        match opration.operation_type {
                            //聊天
                            crate::message::OperationType::Chat => match opration.chat {
                                Some(chat) => match chat.chat_type {
                                    crate::message::ChatType::Person => {
                                        log::info!("message:{:?}", message);
                                        //从好友列表中获取聊天好友
                                        let friends_lock = friends_arc.lock().await;
                                        match friends_lock.get(&chat.no) {
                                            Some(friend_arc) => {
                                                let friend_lock = friend_arc.lock().await;
                                                //封装消息
                                                let msg = Message::person_msg(
                                                    self_cc_no.to_string(),
                                                    message.to_string(),
                                                );
                                                friend_lock.write_all(json!(msg).to_string()).await;
                                            }
                                            None => {
                                                let msg = Message::system_msg(format!(
                                                    "{}用户不是您的好友，请先添加好友",
                                                    chat.no
                                                ));
                                                write_clone
                                                    .clone()
                                                    .lock()
                                                    .await
                                                    .write_all(json!(msg).to_string().as_bytes())
                                                    .await
                                                    .unwrap();
                                            }
                                        };
                                    }
                                    crate::message::ChatType::Meet => todo!(),
                                },
                                None => {
                                    log::error!("no one")
                                }
                            },
                            crate::message::OperationType::MakeMeet => todo!(),
                            crate::message::OperationType::UpdateName => todo!(),
                            crate::message::OperationType::JoinMeet => todo!(),
                            OperationType::ExitMeet => todo!(),
                            //添加好友
                            OperationType::AddRequest => {
                                match &opration.add {
                                    Some(add) => {
                                        match add.add_type {
                                            crate::message::AddType::Person => {
                                                match get_user(server_clone.clone(), &add.no).await
                                                {
                                                    Some(friend_arc) => {
                                                        //发送添加好友请求
                                                        let friend_lock = friend_arc.lock().await;
                                                        let  msg = Message::system_msg(format!("{} 想添加您为好友。好友请求：{} \n是否同意？同意输入：Y，否则输入：N\n",self_cc_no.clone(),opration.message));
                                                        friend_lock
                                                            .write_all(json!(msg).to_string())
                                                            .await;
                                                        friend_lock.add_quest.lock().await.insert(
                                                            self_cc_no.clone(),
                                                            opration.clone(),
                                                        );
                                                    }
                                                    None => {
                                                        let msg = Message::system_msg(format!(
                                                            "用户:{} 不存在，不能添加为您的好友\n",
                                                            &add.no
                                                        ));
                                                        write_clone
                                                            .clone()
                                                            .lock()
                                                            .await
                                                            .write_all(
                                                                json!(msg).to_string().as_bytes(),
                                                            )
                                                            .await
                                                            .unwrap();
                                                    }
                                                }
                                            }
                                            crate::message::AddType::Meet => todo!(),
                                        }
                                    }
                                    None => {
                                        log::error!("no one")
                                    }
                                }
                            }

                            OperationType::AddAnswer => {
                                match &opration.add {
                                    Some(add) => match add.add_type {
                                        crate::message::AddType::Person => {
                                            match add_request_arc.lock().await.get(&add.no) {
                                                Some(_) => {
                                                    let msg = opration.message.as_str();
                                                    match msg {
                                                        "Y\n" => {
                                                            // 双方好友列表互相添加对方
                                                            let myself = get_user(
                                                                server_clone.clone(),
                                                                &self_cc_no,
                                                            )
                                                            .await
                                                            .unwrap();
                                                            let friend = get_user(
                                                                server_clone.clone(),
                                                                &add.no,
                                                            )
                                                            .await
                                                            .unwrap();
                                                            myself
                                                                .clone()
                                                                .lock()
                                                                .await
                                                                .friends
                                                                .lock()
                                                                .await
                                                                .insert(
                                                                    add.no.to_string(),
                                                                    friend.clone(),
                                                                );
                                                            friend
                                                                .clone()
                                                                .lock()
                                                                .await
                                                                .friends
                                                                .lock()
                                                                .await
                                                                .insert(
                                                                    self_cc_no.clone(),
                                                                    myself.clone(),
                                                                );
                                                            let myself_msg =
                                                                Message::system_msg(format!(
                                                                    "您已经添加{}为好友。\n",
                                                                    friend.lock().await.cc_no
                                                                ));
                                                            //通知添加好友成功
                                                            myself
                                                                .lock()
                                                                .await
                                                                .write_all(
                                                                    json!(myself_msg).to_string(),
                                                                )
                                                                .await;

                                                            let friend_msg =
                                                                Message::system_msg(format!(
                                                                    "您已经添加{}为好友。\n",
                                                                    myself.lock().await.cc_no
                                                                ));

                                                            friend
                                                                .lock()
                                                                .await
                                                                .write_all(
                                                                    json!(friend_msg).to_string(),
                                                                )
                                                                .await;
                                                        }
                                                        //TODO: 不同意
                                                        "N\n" => {
                                                            log::info!("同意")
                                                        }
                                                        _ => {
                                                            let msg = Message::system_msg(
                                                                "请输入[Y]或[N]答复好友请求\n"
                                                                    .to_string(),
                                                            );
                                                            write_clone
                                                                .lock()
                                                                .await
                                                                .write_all(
                                                                    json!(msg)
                                                                        .to_string()
                                                                        .as_bytes(),
                                                                )
                                                                .await
                                                                .unwrap();
                                                        }
                                                    }
                                                }
                                                None => {
                                                    let msg = Message::system_msg(format!(
                                                        "{}用户并没有向您发出请求，同意无效\n",
                                                        &add.no
                                                    ));
                                                    write_clone
                                                        .lock()
                                                        .await
                                                        .write_all(
                                                            json!(msg).to_string().as_bytes(),
                                                        )
                                                        .await
                                                        .unwrap();
                                                }
                                            }
                                        }
                                        crate::message::AddType::Meet => todo!(),
                                    },
                                    None => {
                                        log::error!("no request")
                                    }
                                }
                            }
                            OperationType::RemoveFriend => todo!(),
                            OperationType::FriendList => {
                                let friends_lock = friends_arc.lock().await;
                                let mut write_lock = write_clone.lock().await;
                                write_lock
                                    .write_all("您的好友列表：\n".as_bytes())
                                    .await
                                    .unwrap();

                                let mut msg_context = String::new();

                                for (_, user) in &*friends_lock {
                                    let username = {
                                        let user_lock = user.lock().await;
                                        user_lock.name.clone()
                                    };
                                    msg_context.push_str(&username);
                                    msg_context.push('\n');
                                }
                                let msg = Message::system_msg(msg_context);

                                write_lock
                                    .write_all(json!(msg).to_string().as_bytes())
                                    .await
                                    .unwrap();
                            }
                            OperationType::MeetList => todo!(),
                            OperationType::AddRequestList => todo!(),
                        }
                    }
                    None => {
                        let msg = Message::system_msg("格式错误，请重新输入\n".to_string());
                        write_clone
                            .lock()
                            .await
                            .write_all(json!(msg).to_string().as_bytes())
                            .await
                            .unwrap();
                    }
                }
                //清空缓存
                buf[..n].iter_mut().for_each(|b| *b = 0);
            }
        });
    }
    async fn write_all(&self, msg: String) {
        let mut write_lock = self.write.lock().await;
        write_lock.write_all(msg.as_bytes()).await.unwrap();
        drop(write_lock)
    }

    async fn add_friend(&mut self, friend: Arc<Mutex<User>>) {
        let friend_clone = friend.clone();
        self.friends
            .lock()
            .await
            .insert(friend_clone.lock().await.cc_no.clone(), friend)
            .unwrap();
    }
}

async fn get_user(server: Arc<Mutex<Server>>, no: &str) -> Option<Arc<Mutex<User>>> {
    server.lock().await.users.get(no).cloned()
}

//TODO:监听所有用户以及群聊发来的消息
//
//
//
//
//
